package com.ruoyi.system.service.impl;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.ScrewConfig;
import com.ruoyi.system.mapper.ScrewConfigMapper;
import com.ruoyi.system.service.IScrewConfigService;
import com.ruoyi.system.service.ISendMailService;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

import static cn.smallbun.screw.core.engine.EngineConfig.builder;

/**
 * screwConfigService业务层处理
 *
 * @author 李奎
 * @date 2023-11-13
 */
@Service
public class ScrewConfigServiceImpl implements IScrewConfigService {
    @Resource private ScrewConfigMapper screwConfigMapper;

    @Resource private ISendMailService sendMailService;

    /**
     * 查询screwConfig
     *
     * @param screwId screwConfig主键
     * @return screwConfig
     */
    @Override
    public ScrewConfig selectScrewConfigByScrewId( Long screwId ) {
        return screwConfigMapper.selectScrewConfigByScrewId( screwId );
    }

    /**
     * 查询screwConfig列表
     *
     * @param screwConfig screwConfig
     * @return screwConfig
     */
    @Override
    public List<ScrewConfig> selectScrewConfigList( ScrewConfig screwConfig ) {
        return screwConfigMapper.selectScrewConfigList( screwConfig );
    }

    /**
     * 新增screwConfig
     *
     * @param screwConfig screwConfig
     * @return 结果
     */
    @Override
    public int insertScrewConfig( ScrewConfig screwConfig ) {
        screwConfig.setCreateTime( DateUtils.getNowDate( ) );
        return screwConfigMapper.insertScrewConfig( screwConfig );
    }

    /**
     * 修改screwConfig
     *
     * @param screwConfig screwConfig
     * @return 结果
     */
    @Override
    public int updateScrewConfig( ScrewConfig screwConfig ) {
        screwConfig.setUpdateTime( DateUtils.getNowDate( ) );
        return screwConfigMapper.updateScrewConfig( screwConfig );
    }

    /**
     * 批量删除screwConfig
     *
     * @param screwIds 需要删除的screwConfig主键
     * @return 结果
     */
    @Override
    public int deleteScrewConfigByScrewIds( Long[] screwIds ) {
        return screwConfigMapper.deleteScrewConfigByScrewIds( screwIds );
    }

    /**
     * 删除screwConfig信息
     *
     * @param screwId screwConfig主键
     * @return 结果
     */
    @Override
    public int deleteScrewConfigByScrewId( Long screwId ) {
        return screwConfigMapper.deleteScrewConfigByScrewId( screwId );
    }


    /**
     * 生成文档
     *
     * @param screwId screwConfig主键
     * @return
     */
    @Override
    public String generateDocument( Long screwId ) {
        try {
            ScrewConfig screwConfig = screwConfigMapper.selectScrewConfigByScrewId( screwId );
            if ( screwConfig == null ) {
                return "配置信息不存在";
            }

            if ( screwConfig.getDataBaseType( ).equalsIgnoreCase( "mysql" ) ) {
                this.mySqlGenerator( screwConfig );
            } else {
                return "目前只是支持mysql数据库";
            }

            return "成功";
        } catch ( Exception e ) {
            e.printStackTrace( );
            return "失败";
        }


    }

    public void mySqlGenerator( ScrewConfig screwConfig ) {
        //数据源
        HikariConfig hikariConfig = new HikariConfig( );
        if ( screwConfig.getDataBaseVersion( ).equals( "5" ) ) {
            hikariConfig.setDriverClassName( "com.mysql.jdbc.Driver" );

        } else if ( screwConfig.getDataBaseVersion( ).equals( "8" ) ) {
            hikariConfig.setDriverClassName( "com.mysql.cj.jdbc.Driver" );
        }

        hikariConfig.setJdbcUrl( screwConfig.getDataBaseUrl() );
        hikariConfig.setUsername( screwConfig.getDataBaseUserName());
        hikariConfig.setPassword( screwConfig.getDataBasePassword() );

        //设置可以获取tables remarks信息
        hikariConfig.addDataSourceProperty( "useInformationSchema", "true" );
        hikariConfig.setMinimumIdle( 2 );
        hikariConfig.setMaximumPoolSize( 5 );
        DataSource dataSource = new HikariDataSource( hikariConfig );
        //生成配置
        String fileOutputDir = "D:\\桌面文件";
        EngineConfig engineConfig = builder( )
                //生成文件路径
                .fileOutputDir( fileOutputDir )
                //打开目录
                .openOutputDir( true )
                //文件类型
                .fileType( EngineFileType.WORD )
                //生成模板实现
                .produceType( EngineTemplateType.freemarker )
                //自定义文件名称
//                .fileName( "自定义文件名称" ).build( );
                .fileName( screwConfig.getConfigName() ).build( );

        //忽略表
        ArrayList<String> ignoreTableName = new ArrayList<>( );
        ignoreTableName.add( "test_user" );
        ignoreTableName.add( "test_group" );
        //忽略表前缀
        ArrayList<String> ignorePrefix = new ArrayList<>( );
        ignorePrefix.add( "test_" );
        //忽略表后缀
        ArrayList<String> ignoreSuffix = new ArrayList<>( );
        ignoreSuffix.add( "_test" );
        ProcessConfig processConfig = ProcessConfig.builder( )
                //指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时，将生成指定表，其余表不生成、并跳过忽略表配置
                //根据名称指定表生成
                .designatedTableName( new ArrayList<>( ) )
                //根据表前缀生成
                .designatedTablePrefix( new ArrayList<>( ) )
                //根据表后缀生成
                .designatedTableSuffix( new ArrayList<>( ) )
                //忽略表名
                .ignoreTableName( ignoreTableName )
                //忽略表前缀
                .ignoreTablePrefix( ignorePrefix )
                //忽略表后缀
                .ignoreTableSuffix( ignoreSuffix ).build( );
        //配置
        Configuration config = Configuration.builder( )
                //版本
                .version( "1.0.0" )
                //描述
                .description( screwConfig.getConfigName()+"数据库设计文档生成" )
                //数据源
                .dataSource( dataSource )
                //生成配置
                .engineConfig( engineConfig )
                //生成配置
                .produceConfig( processConfig )
                .build( );
        //执行生成
        new DocumentationExecute( config ).execute( );
    }


}
